﻿using System;
using System.ServiceModel;
using System.Collections.Generic;

// Microsoft Dynamics CRM namespace(s)
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using SSSToolbox;

namespace CRMToolbox
{
    public class ProfilerPreventSave : IPlugin
    {
        public void Execute(IServiceProvider serviceProvider)
        {
            //Extract the tracing service for use in debugging sandboxed plug-ins.
            ITracingService tracingService =
                (ITracingService)serviceProvider.GetService(typeof(ITracingService));

            // Obtain the execution context from the service provider.
            IPluginExecutionContext context = (IPluginExecutionContext)
                serviceProvider.GetService(typeof(IPluginExecutionContext));

            IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
            IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);

            // The InputParameters collection contains all the data passed in the message request.
            if (context.InputParameters.Contains("Target") &&
                context.InputParameters["Target"] is Entity)
            {
                // Obtain the target entity from the input parameters.
                Entity entity = (Entity)context.InputParameters["Target"];

                // Verify that the target entity represents an account.
                // If not, this plug-in was not registered correctly.
                if (entity.LogicalName != "crmtb_profiler")
                    return;

                try
                {
                   if (entity.Attributes.Contains("crmtb_mailboxid"))
                    {
                        EntityReference mailbox = (EntityReference)entity["crmtb_mailboxid"];
                        Guid mailboxid = mailbox.Id;
                        EntityCollection Profilers = GetProfilers(service, mailboxid);
                        CheckAndThrowErrorIfNeeded(Profilers);
                        
                    }
                   else
                    {
                        return;
                    }

                }
                catch (FaultException<OrganizationServiceFault> ex)
                {
                    throw new InvalidPluginExecutionException("An error occurred in the Profiler plug-in.", ex);
                }

                catch (Exception ex)
                {
                    tracingService.Trace("Profiler Plugin: {0}", ex.ToString());
                    throw;
                }
            }
        }

        private void CheckAndThrowErrorIfNeeded(EntityCollection profilers)
        {
            if (profilers.Entities.Count > 1)
            {
                throw new InvalidPluginExecutionException("Found an existing profiler record associated with the current mailbox. Save operation aborted.");
            }
        }

        private EntityCollection GetProfilers(IOrganizationService service, Guid mailboxid)
        {
            QueryByAttribute query = new QueryByAttribute("crmtb_profiler")
            {
                ColumnSet = new ColumnSet("crmtb_mailboxid")
            };
            query.Attributes.AddRange("crmtb_mailboxid");
            query.Values.AddRange(mailboxid);

            EntityCollection results = service.RetrieveMultiple(query);

            return results;
        }
    }
}
